/**
 * 中间件集成
 * Middleware Integration
 */

const {
  rateLimitConfig,
  helmetConfig,
  xssProtection,
  sqlInjectionProtection,
  inputValidation,
  fileUploadSecurity,
  csrfProtection,
  requestLogger
} = require('./security');

/**
 * 应用安全中间件到Express应用
 */
function applySecurity(app) {
  // 请求日志
  app.use(requestLogger);

  // 安全头
  app.use(helmetConfig);

  // 通用频率限制
  app.use('/api/', rateLimitConfig.general);

  // XSS防护
  app.use(xssProtection);

  // SQL注入防护
  app.use(sqlInjectionProtection);

  // 认证相关路由的特殊限制
  app.use('/api/auth/login', rateLimitConfig.auth);
  app.use('/api/auth/register', rateLimitConfig.auth);

  // 文件上传路由的特殊限制
  app.use('/api/files/upload', rateLimitConfig.upload);

  // 管理员路由的特殊限制
  app.use('/api/admin/', rateLimitConfig.admin);

  // CSRF保护（排除GET请求）
  app.use((req, res, next) => {
    if (req.method === 'GET') {
      return next();
    }
    return csrfProtection(req, res, next);
  });
}

/**
 * 应用输入验证中间件
 */
function applyInputValidation(app) {
  // 用户注册和更新路由
  app.use('/api/auth/login', inputValidation.email);
  app.use('/api/auth/register', [
    inputValidation.email,
    inputValidation.password,
    inputValidation.nickname
  ]);
  app.use('/api/user/profile', inputValidation.nickname);
  app.use('/api/user/password', inputValidation.password);

  // 管理员用户管理路由
  app.use('/api/admin/users', [
    inputValidation.email,
    inputValidation.nickname
  ]);

  // 文件相关路由
  app.use('/api/files/', inputValidation.filePath);
}

/**
 * 应用文件上传安全中间件
 */
function applyFileUploadSecurity(app) {
  // 文件上传路由
  app.use('/api/files/upload', [
    fileUploadSecurity.validateFile,
    fileUploadSecurity.validateFileContent
  ]);

  // 头像上传路由
  app.use('/api/user/avatar', [
    fileUploadSecurity.validateFile,
    fileUploadSecurity.validateFileContent
  ]);
}

module.exports = {
  applySecurity,
  applyInputValidation,
  applyFileUploadSecurity,
  rateLimitConfig,
  helmetConfig,
  xssProtection,
  sqlInjectionProtection,
  inputValidation,
  fileUploadSecurity,
  csrfProtection,
  requestLogger
};